package algo3.modelo.barcos;
import java.util.ArrayList;

import algo3.modelo.Direccion;
import algo3.modelo.IModificablePorTurnos;
import algo3.modelo.IPosicionable;
import algo3.modelo.Posicion;
import algo3.modelo.armas.Danio;
import algo3.modelo.partes.ParteBarco;

public abstract class Barco implements IPosicionable, IModificablePorTurnos {
	
	protected int tamanio;
	protected Posicion posicionPopa;
	protected Direccion direccion;
	protected Direccion orientacion;
	protected ArrayList<ParteBarco> partes;

	public enum Estado {
		PERFECTO, DANIADO, HUNDIDO;
	}

	public Barco(Posicion posicionPopa, Direccion direccion, Direccion orientacion){
		this.posicionPopa = posicionPopa;
		this.direccion = direccion;
		this.orientacion = orientacion;
		this.setTamanio();
		this.crearPartes();
	}

	public Barco(Posicion posicionPopa, Direccion direccion, Direccion orientacion, int tamanio){
		this.posicionPopa = posicionPopa;
		this.direccion = direccion;
		this.orientacion = orientacion;
		this.tamanio = tamanio;
		this.crearPartes();
	}

	abstract void setTamanio();

	protected void crearPartes(){
		this.partes = new ArrayList<ParteBarco>();
		Posicion posicionAuxiliar = new Posicion(this.posicionPopa);
		for(int i=0; i < this.tamanio; i += 1){
			ParteBarco parte = this.crearParte();
			parte.setPosicion(posicionAuxiliar);
			this.partes.add(parte);
			posicionAuxiliar = posicionAuxiliar.proximaEnDireccion(this.orientacion);
		}
	}

	protected ParteBarco crearParte(){
		return new ParteBarco();
	}
	
	public Posicion getPosicion() {		
		return this.posicionPopa;
	}

	public void setPosicion(Posicion posicion) {
		this.posicionPopa = posicion;
	}
		
	public int getTamanio(){
		return tamanio;
	}

	public Direccion getDireccion(){
		return this.direccion;
	}
	
	public Estado getEstado(){
		int partesDestruidas = 0;
		Estado resultado = null;
		for(ParteBarco parte : this.partes){
			if (parte.getEstado() == "DESTRUIDA"){
				partesDestruidas += 1;
			}
		}
		if (partesDestruidas == this.tamanio){
			resultado = Estado.HUNDIDO;
		} else if (partesDestruidas > 0) {
			resultado = Estado.DANIADO;
		} else {
			resultado = Estado.PERFECTO;
		}
		return resultado;		
	}
	
	public void invertirDireccion(){
		this.direccion = this.direccion.inversa();
	}	
	
	public ArrayList<Posicion> posicionesOcupadas(){
		ArrayList<Posicion> posiciones = new ArrayList<Posicion>();
		for(ParteBarco parte : this.partes){
			posiciones.add(parte.getPosicion());
		}
		return posiciones;
	}

	public void avanzar() {
		this.posicionPopa = this.posicionPopa.proximaEnDireccion(this.direccion);
		Posicion posicionAuxiliar = new Posicion(this.posicionPopa);
		for(ParteBarco parte : this.partes){
			parte.setPosicion(posicionAuxiliar);
			posicionAuxiliar = posicionAuxiliar.proximaEnDireccion(this.orientacion);
		}
	}
	
	public void recibirDanio(Danio danio){
		for (ParteBarco parte: this.partes){
			parte.recibirDanio(danio);
		}
	}

	public void avanzarTurno() {
		this.avanzar();
	}
	
	public ArrayList<ParteBarco> getPartes(){
		return partes;
	}
}
